vue-router源码分析(VueRouter内部方法)

VueRouter内部方法

1. match

使用:this.$router.match('/count')

输入参数raw(/user/4739284722这种形式,类似route的path),current,redirectedFrom,结果返回匹配route

1
2
3
match(raw: RawLocation, current?: Route, redirectedFrom?: Location): Route {
return this.matcher.match(raw, current, redirectedFrom);
}

2. currentRoute

使用:this.$router.currentRoute
用于获取当前history.current,也就是当前route,包括path、component、meta等

1
2
3
get currentRoute(): ?Route {
return this.history && this.history.current;
}

3. init

4. 全局路由钩子

在路由切换时被调用,经常在router/index.js中,进行路由守卫:router.beforeEach((to,from,next)=>{})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 将回调方法fn注册到beforeHooks里。registerHook会返回,fn执行后的callback方法,功能是将fn从beforeHooks删除
beforeEach(fn: Function): Function {
return registerHook(this.beforeHooks, fn);
}

// 将回调方法fn注册到resolveHooks里。registerHook会返回,fn执行后的callback方法,功能是将fn从resolveHooks删除
beforeResolve(fn: Function): Function {
return registerHook(this.resolveHooks, fn);
}

// 将回调方法fn注册到afterHooks里。registerHook会返回,fn执行后的callback方法,功能是将fn从afterHooks删除
afterEach(fn: Function): Function {
return registerHook(this.afterHooks, fn);
}

registerHook

将callback(参数fn)插入list,返回一个方法,方法实现的是从list中删除fn。也就是在callback执行后,通过调用这个方法,可以将fn从list中移除

1
2
3
4
5
6
7
function registerHook(list: Array<any>, fn: Function): Function {
list.push(fn);
return () => {
const i = list.indexOf(fn);
if (i > -1) list.splice(i, 1);
};
}

5. 改变路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// 将回调方法fn注册到afterHooks里。registerHook会返回,fn执行后的callback方法,功能是将fn从afterHooks删除
afterEach(fn: Function): Function {
return registerHook(this.afterHooks, fn);
}

// 添加一个回调函数,它会在首次路由跳转完成时被调用,此方法通常用于等待异步的导航钩子完成,比如在进行服务端渲染中
onReady(cb: Function, errorCb?: Function) {
this.history.onReady(cb, errorCb);
}

// 报错
onError(errorCb: Function) {
this.history.onError(errorCb);
}

// 新增路由跳转
push(location: RawLocation, onComplete?: Function, onAbort?: Function) {
// $flow-disable-line
if (!onComplete && !onAbort && typeof Promise !== "undefined") {
return new Promise((resolve, reject) => {
this.history.push(location, resolve, reject);
});
} else {
this.history.push(location, onComplete, onAbort);
}
}

// 路由替换
replace(location: RawLocation, onComplete?: Function, onAbort?: Function) {
// $flow-disable-line
if (!onComplete && !onAbort && typeof Promise !== "undefined") {
return new Promise((resolve, reject) => {
this.history.replace(location, resolve, reject);
});
} else {
this.history.replace(location, onComplete, onAbort);
}
}

// 前进n条路由
go(n: number) {
this.history.go(n);
}

// 后退一步
back() {
this.go(-1);
}

// 前进一步
forward() {
this.go(1);
}

6. getMatchedComponents

使用:this.$router.getMatchedComponents("/")或者this.$router.getMatchedComponents({path: "/count",name: "count"}),返回匹配的组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
getMatchedComponents(to?: RawLocation | Route): Array<any> {
const route: any = to
? to.matched
? to
: this.resolve(to).route
: this.currentRoute;
if (!route) {
return [];
}
return [].concat.apply(
[],
route.matched.map(m => {
return Object.keys(m.components).map(key => {
return m.components[key];
});
})
);
}

resolve

如果this.$router.getMatchedComponents("/")参数是个path,会来到这里解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
resolve(
to: RawLocation,
current?: Route,
append?: boolean
): {
location: Location,
route: Route,
href: string,
// for backwards compat
normalizedTo: Location,
resolved: Route
} {
current = current || this.history.current;
const location = normalizeLocation(to, current, append, this);
const route = this.match(location, current);
const fullPath = route.redirectedFrom || route.fullPath;
const base = this.history.base;
const href = createHref(base, fullPath, this.mode);
return {
location,
route,
href,
// for backwards compat
normalizedTo: location,
resolved: route
};
}

creatHref

建立路由在浏览器中显示的格式

1
2
3
4
function createHref(base: string, fullPath: string, mode) {
var path = mode === "hash" ? "#" + fullPath : fullPath;
return base ? cleanPath(base + "/" + path) : path;
}

7. addRoutes

动态新增路由

1
2
3
4
5
6
7
addRoutes(routes: Array<RouteConfig>) {
this.matcher.addRoutes(routes);
// START是啥???????
if (this.history.current !== START) {
this.history.transitionTo(this.history.getCurrentLocation());
}
}